package com.realife.eson.common.util.network;

import com.realife.eson.common.asserts.AssertNP;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.*;


@Slf4j
public class IpUtil {


    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST = "127.0.0.1";
    private static final String SEPARATOR = ",";

    public static String getIpAddr(HttpServletRequest request) {
        System.out.println(request);
        String ipAddress;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (LOCALHOST.equals(ipAddress)) {
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            // "***.***.***.***".length()
            if (ipAddress != null && ipAddress.length() > 15) {
                if (ipAddress.indexOf(SEPARATOR) > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        return ipAddress;
    }


    /**
     * 构建请求路径后的参数拼接   ?a=x&b=y&....
     * hutool.core.util.URLUtil
     *
     * @return
     */
    @SuppressWarnings("all")
    public static String buildUri(List<String> keyList, List<String> valList) {
        //
        StringBuilder uri = new StringBuilder();
        if (AssertNP.legalParams(keyList, valList)) {
            List<Integer> eleIndex = new ArrayList<>();
            for (int i = 0; i < valList.size(); i++) {
                if (AssertNP.legalParams(valList.get(i))) {
                    eleIndex.add(i);
                }
            }
            if (AssertNP.legalParams(eleIndex)) {
                for (int i = 0; i < eleIndex.size(); i++) {
                    if (i < eleIndex.size() - 1) {
                        uri.append(keyList.get(eleIndex.get(i)));
                        uri.append("=");
                        uri.append(valList.get(eleIndex.get(i)));
                        uri.append("&");
                    } else {
                        uri.append(keyList.get(eleIndex.get(i)));
                        uri.append("=");
                        uri.append(valList.get(eleIndex.get(i)));
                    }
                }
            }
        }

        return uri.toString();
    }


    /**
     * 构建请求路径后的参数拼接   ?a=x&b=y&....
     * hutool.core.util.URLUtil
     *
     * @return
     */
    @SuppressWarnings("all")
    public static String buildUri1(List<String> keyList, List<Object> valList) {
        //
        StringBuilder uri = new StringBuilder();
        if (AssertNP.legalParams(keyList, valList)) {
            List<Integer> eleIndex = new ArrayList<>();
            for (int i = 0; i < valList.size(); i++) {
                if (AssertNP.legalParams(valList.get(i))) {
                    eleIndex.add(i);
                }
            }
            if (AssertNP.legalParams(eleIndex)) {
                for (int i = 0; i < eleIndex.size(); i++) {
                    if (i < eleIndex.size() - 1) {
                        uri.append(keyList.get(eleIndex.get(i)));
                        uri.append("=");
                        uri.append(valList.get(eleIndex.get(i)));
                        uri.append("&");
                    } else {
                        uri.append(keyList.get(eleIndex.get(i)));
                        uri.append("=");
                        uri.append(valList.get(eleIndex.get(i)));
                    }
                }
            }
        }

        return uri.toString();
    }


    /**
     * @param preUrl      前置路径
     * @param pathVarList 路径变量值
     * @param uriMap      ?拼接的参数对
     * @return
     */
    public static String getFullPath(String preUrl, List<Object> pathVarList, Map<String, Object> uriMap) {
        //
        String fullPath = preUrl;
        //
        StringBuilder builder = new StringBuilder();
        if (AssertNP.legalParams(pathVarList)) {
            for (Object pathVar : pathVarList) {
                if (AssertNP.legalParams(pathVar)) {
                    builder.append("/" + pathVar);
                }
            }
            fullPath += builder.toString();
        }

        //
        String uriStr = "";
        if (AssertNP.legalParams(uriMap)) {
            List<String> keyList = new ArrayList<>();
            List<Object> valList = new ArrayList<>();
            for (String key : uriMap.keySet()) {
                keyList.add(key);
                valList.add(uriMap.get(key));
            }
            uriStr = buildUri1(keyList, valList);
            //
            if (AssertNP.legalParams(uriStr)) {
                fullPath += "?" + uriStr;
            }
        }
        return fullPath;
    }


    public static Map<String, Object> getUrlParamPair(List<String> key, List<Object> val) {
        Map<String, Object> urlParamPair = new HashMap<>();
        for (int i = 0; i < key.size(); i++) {
            urlParamPair.put(key.get(i), val.get(i));
        }
        return urlParamPair;
    }


    /**
     * 本机地址
     *
     * @return
     * @throws SocketException
     */
    public static List<String> getIpAddress() {
        List<String> list = null;
        try {
            list = new LinkedList<>();
            Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
            while (enumeration.hasMoreElements()) {
                NetworkInterface network = (NetworkInterface) enumeration.nextElement();
                if (network.isVirtual() || !network.isUp()) {
                    continue;
                } else {
                    Enumeration addresses = network.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        InetAddress address = (InetAddress) addresses.nextElement();
                        if (address != null && (address instanceof Inet4Address || address instanceof Inet6Address)) {
                            list.add(address.getHostAddress());
                        }
                    }
                }
            }
        } catch (SocketException e) {
            log.info("[**==> {} **]", e.getMessage() + " >>" + e.getStackTrace()[0] + " >>" + e.getCause());
        } finally {
        }
        return list;
    }


    /**
     * 获取全部存放本机IP地址
     *
     * @return
     * @throws SocketException
     */
    public static List<String> getAllIpAddress() {
        List<String> list = null;
        try {
            list = new LinkedList<>();
            Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
            while (enumeration.hasMoreElements()) {
                NetworkInterface network = (NetworkInterface) enumeration.nextElement();
                Enumeration addresses = network.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress address = (InetAddress) addresses.nextElement();
                    if (address != null && (address instanceof Inet4Address || address instanceof Inet6Address)) {
                        list.add(address.getHostAddress());
                    }
                }
            }
        } catch (SocketException e) {
            log.info("[**==> {} **]", e.getMessage() + " >>" + e.getStackTrace()[0] + " >>" + e.getCause());
        } finally {
        }
        return list;
    }


    public static void main(String[] args) {

        List<String> keyList = new ArrayList<>(Arrays.asList("name", "refresh", "resourceVersion", "selector", "repo"));
        List<String> valList = new ArrayList<>(Arrays.asList("vo.getName()", "", " ".trim(), "vo.getSelector()", ""));

        String str = buildUri(keyList, valList);
        //https://10.10.33.136:32579/api/v1/repositories/http://58.210.154.140:8888/zhanggc/appstore/mynginx.git/appdetails
        System.out.println("str = " + str);


        //
        List<String> allIpAddress = getIpAddress();
        allIpAddress.forEach(System.out::println);
        System.out.println("allIpAddress = " + allIpAddress.toString());


        //
        //保证顺序
        List<Object> pathVarList = new ArrayList<>(Arrays.asList("zhangsan", "lisi", 100));
        //不用保证顺序
        Map<String, Object> uriMap = new HashMap<>();
        uriMap.put("username", "xiaoming");
        uriMap.put("password", "123456");
        List<String> roleList = new ArrayList<>(Arrays.asList("admin", "superman", "haha"));
        uriMap.put("roleList", roleList);
        String fullPath = getFullPath("https://www.baidu.com/app", pathVarList, uriMap);

        // https://www.baidu.com/app/zhangsan/lisi/100?password=123456&roleList=[admin, superman, haha]&username=xiaoming
        System.out.println(fullPath);


        List<Object> objects = Collections.emptyList();
        System.out.println("objects.size() = " + objects.size());// 0
        System.out.println("AssertNP.legalParams(objects) = " + AssertNP.legalParams(objects));// false
    }

}

